home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
sos3-2.lha
/
src
/
agg
/
List.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-23
|
20KB
|
663 lines
/* --------------------------------------------------------------------------
* Copyright 1992 by Forschungszentrum Informatik (FZI)
*
* You can use and distribute this software under the terms of the licence
* you should have received along with this program.
* If not or if you want additional information, write to
* Forschungszentrum Informatik, "STONE", Haid-und-Neu-Strasse 10-14,
* D-7500 Karlsruhe 1, Germany.
* --------------------------------------------------------------------------
*/
// **************************************************************************
// Module List 03/07/89 Bernhard Schiefer (bs)
// modified : 24/10/91 (bs)
// **************************************************************************
// implements methods of classes: List, sos_List_node
// **************************************************************************
#include "sys.h"
#include "agg_err.h"
#include "trc_agg.h"
#include "agg_sos.h"
// **************************************************************************
void sos_Object_List::local_initialize (sos_Object_List list)
// **************************************************************************
{ T_PROC ("sos_Object_List::local_initialize");
TT (agg_H, T_ENTER);
list.set_first (sos_List_node::make (NO_OBJECT));
list.set_last (sos_List_node::make (NO_OBJECT));
list.set_cardinality (0);
TT (agg_H, T_LEAVE);
} // ** local_initialize **
// **************************************************************************
void sos_Object_List::local_finalize (sos_Object_List list)
// **************************************************************************
{ T_PROC ("sos_Object_List::local_finalize");
TT (agg_H, T_ENTER);
list.clear();
TT (agg_H, T_LEAVE);
} // ** local_finalize **
// **************************************************************************
void sos_Object_List::append (sos_Object o)
// **************************************************************************
// append an element
{
T_PROC ("sos_Object_List::append");
TT (agg_H, T_ENTER);
sos_List_node cn;
cn = sos_List_node::create (self.container());
cn.set_val (o);
if (self.get_first() == NO_OBJECT) // insert the first node
{ self.set_first (cn);
self.set_last (cn);
cn.set_succ (sos_List_node::make (NO_OBJECT));
cn.set_pred (sos_List_node::make (NO_OBJECT));
}
else
{ sos_List_node n = self.get_last();
n.insert_after (cn);
self.set_last (cn);
}
self.set_cardinality (self.get_cardinality() + 1);
TT (agg_H, T_LEAVE);
} // ** append **
// **************************************************************************
void sos_Object_List::insert (Index position, sos_Object o)
// **************************************************************************
// insert an element at the specified position
// if position 0 is specified insert after the last element
{
T_PROC ("sos_Object_List::insert");
TT (agg_H, T_ENTER; TI (position));
err_assert (position >= 0, "sos_Object_List::insert");
if (position > self.get_cardinality())
position = 0; // insert after last!
if (position == 0)
self.append (o);
else
{ sos_List_node first_node = self.get_first();
sos_List_node cn = sos_List_node::create (self.container());
cn.set_val (o);
if (first_node == NO_OBJECT) // insert the first node
{ self.set_first (cn);
self.set_last (cn);
cn.set_succ (sos_List_node::make (NO_OBJECT));
cn.set_pred (sos_List_node::make (NO_OBJECT));
}
else
{ sos_List_node n = first_node.succ (position - 1);
n.insert_before (cn);
if (position == 1) self.set_first (cn);
}
self.set_cardinality (self.get_cardinality() + 1);
}
TT (agg_H, T_LEAVE);
} // ** insert **
// **************************************************************************
void sos_Object_List::remove (Index position)
// **************************************************************************
{
T_PROC ("sos_Object_List::remove");
TT (agg_H, T_ENTER);
sos_List_node first_node = self.get_first();
err_assert (first_node != NO_OBJECT, "sos_Object_List::remove");
sos_List_node cn = first_node.succ (position - 1);
err_assert (cn != NO_OBJECT, "sos_Object_List::remove");
#ifdef ATT
if (cn.operator==(first_node))
self.set_first (first_node.succ());
if (cn.operator==(self.get_last()))
self.set_last (self.get_last().pred());
#else
if (cn == first_node)
self.set_first (first_node.succ());
if (cn == self.get_last())
self.set_last (self.get_last().pred());
#endif
cn.remove();
self.set_cardinality (self.get_cardinality() - 1);
TT (agg_H, T_LEAVE);
} // ** remove **
// **************************************************************************
sos_Object sos_Object_List::get_nth (Index pos)
// **************************************************************************
{
T_PROC ("sos_Object_List::get_nth");
TT (agg_H, T_ENTER; TI (pos));
sos_List_node cn = self.get_first();
err_assert (cn != NO_OBJECT, "sos_Object_List::get_nth");
cn = cn.succ (pos - 1);
err_assert (cn != NO_OBJECT, "sos_Object_List::get_nth");
sos_Object o = cn.get_val();
TT (agg_H, T_LEAVE);
return o;
} // ** get_nth **
// **************************************************************************
void sos_Object_List::set_nth (Index pos, sos_Object o)
// **************************************************************************
// the value of the sos_Object at Index position is replaced by o
{
T_PROC ("sos_Object_List::set_nth");
TT (agg_H, T_ENTER; TI (pos));
sos_List_node cn = self.get_first();
err_assert (cn != NO_OBJECT, "sos_Object_List::set_nth");
cn = cn.succ (pos - 1);
err_assert (cn != NO_OBJECT, "sos_Object_List::set_nth");
cn.set_val (o);
TT (agg_H, T_LEAVE);
} // ** set_nth **
// **************************************************************************
void sos_Object_List::operator+= (sos_Object_List alist)
// **************************************************************************
{
T_PROC ("sos_Object_List::operator+=");
TT (agg_H, T_ENTER);
for (sos_List_node cn = alist.get_first();
(cn != NO_OBJECT);
(cn = cn.succ()))
self.append (cn.get_val());
TT (agg_H, T_LEAVE);
} // ** operator+= **
// **************************************************************************
Index sos_Object_List::current_pos (sos_Cursor c)
// **************************************************************************
{
T_PROC ("sos_Object_List::current_pos");
TT (agg_H, T_ENTER);
Index result = 0;
err_assert (self.is_valid (c), "sos_Object_List::current_pos");
for (sos_List_node cn = sos_List_node::make (c.get_current());
(cn != NO_OBJECT);
(cn = cn.pred()))
result++;
TT (agg_H, T_LEAVE; TI (result));
return result;
} // ** current_pos **
// **************************************************************************
sos_Bool sos_Object_List::move_cursor (sos_Cursor c, Index position)
// **************************************************************************
{
T_PROC ("sos_Object_List::move_cursor");
TT (agg_H, T_ENTER; TI (position));
err_assert (c.defined_for (self), "sos_Object_List::move_cursor");
sos_Bool success = TRUE;
sos_List_node current = self.get_first();
if (current == NO_OBJECT)
success = FALSE;
else
{ current = current.succ (position - 1);
if (current != NO_OBJECT)
c.set_current (current);
else
success = FALSE;
} // else
TT (agg_H, T_LEAVE; TB(success));
return success;
} // ** move_cursor **
// **************************************************************************
void sos_Object_List::insert_before (sos_Cursor c, sos_Object o)
// **************************************************************************
{
T_PROC ("sos_Object_List::insert_before");
TT (agg_H, T_ENTER);
err_assert (self.is_valid (c), "sos_Object_List::insert_before");
sos_List_node cn = sos_List_node::create (self.container());
cn.set_val (o);
sos_List_node::make (c.get_current()).insert_before (cn);
self.set_cardinality (self.get_cardinality() + 1);
if (cn.pred() == NO_OBJECT)
self.set_first (cn);
TT (agg_H, T_LEAVE);
}
// **************************************************************************
void sos_Object_List::insert_after (sos_Cursor c, sos_Object o)
// **************************************************************************
{
T_PROC ("sos_Object_List::insert_after");
TT (agg_H, T_ENTER);
err_assert (self.is_valid (c), "sos_Object_List::insert_after");
sos_List_node cn = sos_List_node::create (self.container());
cn.set_val (o);
sos_List_node::make (c.get_current()).insert_after (cn);
self.set_cardinality (self.get_cardinality() + 1);
if (cn.succ() == NO_OBJECT)
self.set_last (cn);
TT (agg_H, T_LEAVE);
}
// **************************************************************************
void sos_Object_List::local_assign (sos_Object_List x, sos_Object o)
// **************************************************************************
{
T_PROC ("sos_Object_List::local_assign");
TT (agg_H, T_ENTER );
sos_Object_List y = sos_Object_List::make (o);
x.clear();
x.operator+= (y);
TT (agg_H, T_LEAVE);
} // ** local_assign **
// **************************************************************************
sos_Bool sos_Object_List::local_equal (sos_Object_List x,
sos_Object o,
sos_Eq_kind eq_kind)
// **************************************************************************
{
T_PROC ("sos_Object_List::local_equal");
TT (agg_H, T_ENTER );
sos_Bool result;
if ((eq_kind EQ EQ_STRONG AND NOT o.has_type (x.type())) OR
(eq_kind EQ EQ_WEAK AND NOT o.isa (x.type())))
result = FALSE;
else
{ sos_Object_List y = sos_Object_List::make (o);
if (x.get_cardinality() != y.get_cardinality())
result = FALSE;
else
{ result = TRUE;
sos_Bool based_on_equal = x.get_based_on_equal();
sos_Int comp = 0;
agg_iterate_double (x, sos_Object x_e, y, sos_Object y_e, comp)
{ result = agg_same_entity (x_e, y_e, based_on_equal, eq_kind);
if (NOT result) break;
}
agg_iterate_double_end (x, x_e, y, y_e, comp);
result = (sos_Bool)(result AND comp == 0);
}
}
TT (agg_H, T_LEAVE; TB(result));
return result;
} // ** local_equal **
// **************************************************************************
sos_Int sos_Object_List::local_hash_value (sos_Object_List x)
// **************************************************************************
{
T_PROC ("sos_Object_List::local_hash_value");
TT (agg_H, T_ENTER );
sos_Int result;
if (x.is_empty())
result = 0;
else
result = x.get_nth (1).hash_value();
TT (agg_H, T_LEAVE; TB(result));
return result;
} // ** local_hash_value **
// **************************************************************************
sos_Object sos_Object_List::get (sos_Cursor c)
// **************************************************************************
{
T_PROC ("sos_Object_List::get (sos_Cursor)");
TT (agg_H, T_ENTER);
err_assert (self.is_valid (c), "sos_Object_List::get (sos_Cursor)");
sos_Object o = sos_List_node::make (c.get_current()).get_val();
TT (agg_H, T_LEAVE);
return o;
} // ** get **
// **************************************************************************
void sos_Object_List::set (sos_Cursor c, sos_Object o)
// **************************************************************************
{
T_PROC ("sos_Object_List::set");
TT (agg_H, T_ENTER);
err_assert (self.is_valid (c), "sos_Object_List::set");
sos_List_node::make (c.get_current()).set_val (o);
TT (agg_H, T_LEAVE);
} // ** set **
// **************************************************************************
void sos_Object_List::remove_at (sos_Cursor c)
// **************************************************************************
{
T_PROC ("sos_Object_List::remove_at");
TT (agg_H, T_ENTER);
err_assert (self.is_valid (c), "sos_Object_List::remove_at");
sos_List_node n = sos_List_node::make (c.get_current());
#ifdef ATT
if (n.operator==(self.get_first()))
self.set_first (self.get_first().succ());
if (n.operator==(self.get_last()))
self.set_last (self.get_last().pred());
#else
if (n == self.get_first())
self.set_first (self.get_first().succ());
if (n == self.get_last())
self.set_last (self.get_last().pred());
#endif
self.to_succ (c);
n.remove();
self.set_cardinality (self.get_cardinality() - 1);
TT (agg_H, T_LEAVE);
} // ** remove_at **
// **************************************************************************
sos_Int sos_Object_List::card ()
// **************************************************************************
{
T_PROC ("sos_Object_List::card");
TT (agg_H, T_ENTER);
sos_Int crd = self.get_cardinality();
TT (agg_H, T_LEAVE);
return crd;
} // ** card **
// **************************************************************************
sos_Cursor sos_Object_List::open_cursor (sos_Container ct)
// **************************************************************************
{
// creates a new cursor-object and positions it
// to the first element
T_PROC ("sos_Object_List::open_cursor");
TT (agg_H, T_ENTER);
sos_Cursor new_c = sos_Cursor::create (ct, self);
new_c.set_current (self.get_first());
TT (agg_H, T_LEAVE);
return new_c;
} // ** open_cursor **
// **************************************************************************
void sos_Object_List::close_cursor (sos_Cursor c)
// **************************************************************************
{
// The result of any operation using sos_Cursor c
// is undefined after this operation.
T_PROC ("sos_Object_List::close_cursor");
TT (agg_H, T_ENTER);
err_assert (c.defined_for (self), "sos_Object_List::close_cursor");
c.destroy();
TT (agg_H, T_LEAVE);
} // ** close_cursor **
// **************************************************************************
sos_Cursor sos_Object_List::duplicate (sos_Cursor c)
// **************************************************************************
{
// creates a new cursor-object for the Aggregate and
// positions it on the same element as c
T_PROC ("sos_Object_List::duplicate");
TT (agg_H, T_ENTER);
err_assert (c.defined_for (self), "sos_Object_List::duplicate");
sos_Cursor new_c = sos_Cursor::create (c.container(), self);
new_c.set_current (c.get_current());
TT (agg_H, T_LEAVE);
return new_c;
} // ** duplicate **
// **************************************************************************
sos_Bool sos_Object_List::is_valid (sos_Cursor c)
// **************************************************************************
{
T_PROC ("sos_Object_List::is_valid");
TT (agg_H, T_ENTER);
err_assert (c.defined_for (self), "sos_Object_List::is_valid");
sos_Bool valid = (c.get_current() != NO_OBJECT);
TT (agg_H, T_LEAVE; TB(valid));
return valid;
} // ** is_valid **
// **************************************************************************
sos_Bool sos_Object_List::to_first (sos_Cursor c)
// **************************************************************************
{
T_PROC ("sos_Object_List::to_first");
TT (agg_H, T_ENTER);
err_assert (c.defined_for (self), "sos_Object_List::to_first");
sos_List_node first = self.get_first();
c.set_current (first);
sos_Bool valid = (first != NO_OBJECT);
TT (agg_H, T_LEAVE; TB(valid));
return valid;
} // ** to_first **
// **************************************************************************
sos_Bool sos_Object_List::to_last (sos_Cursor c)
// **************************************************************************
{
T_PROC ("sos_Object_List::to_last");
TT (agg_H, T_ENTER);
err_assert (c.defined_for (self), "sos_Object_List::to_last");
sos_List_node last = self.get_last();
c.set_current (last);
sos_Bool valid = (last != NO_OBJECT);
TT (agg_H, T_LEAVE; TB(valid));
return valid;
} // ** to_last **
// **************************************************************************
sos_Bool sos_Object_List::to_succ (sos_Cursor c, sos_Int i)
// **************************************************************************
{
// Move the sos_Cursor to the i-th successing element
// The function returns FALSE if no such element exists.
T_PROC ("sos_Object_List::to_succ");
TT (agg_H, T_ENTER; TI (i));
err_assert (self.is_valid (c), "sos_Object_List::to_succ");
sos_List_node succ = (sos_List_node::make (c.get_current())).succ (i);
c.set_current (succ);
sos_Bool valid = (succ != NO_OBJECT);
TT (agg_H, T_LEAVE; TB(valid));
return (valid);
} // ** to_succ **
// **************************************************************************
sos_Bool sos_Object_List::to_pred (sos_Cursor c, sos_Int i)
// **************************************************************************
{
// Move the sos_Cursor to the previous i-th element
// The function returns FALSE if no such element exists.
T_PROC ("sos_Object_List::to_pred");
TT (agg_H, T_ENTER; TI (i));
err_assert (self.is_valid (c), "sos_Object_List::to_pred");
sos_List_node pred = (sos_List_node::make (c.get_current())).pred (i);
c.set_current (pred);
sos_Bool valid = (pred != NO_OBJECT);
TT (agg_H, T_LEAVE; TB(valid));
return (valid);
} // ** to_pred **
// *************************** sos_List_node **************************
// **************************************************************************
void sos_List_node::insert_before (sos_List_node n)
// **************************************************************************
{
T_PROC ("sos_List_node::insert_before");
TT (agg_H, T_ENTER);
sos_List_node pred = self.get_pred();
n.set_pred (pred);
n.set_succ (self);
self.set_pred (n);
if (pred != NO_OBJECT) pred.set_succ (n);
TT (agg_H, T_LEAVE);
} // ** insert_before **
// **************************************************************************
void sos_List_node::insert_after (sos_List_node n)
// **************************************************************************
{
T_PROC ("sos_List_node::insert_after");
TT (agg_H, T_ENTER);
sos_List_node succ = self.get_succ();
n.set_pred (self);
n.set_succ (succ);
self.set_succ (n);
if (succ != NO_OBJECT) succ.set_pred (n);
TT (agg_H, T_LEAVE);
} // ** insert_after **
// **************************************************************************
void sos_List_node::remove ()
// **************************************************************************
{
T_PROC ("sos_List_node::remove");
TT (agg_H, T_ENTER);
sos_List_node pred = self.get_pred();
sos_List_node succ = self.get_succ();
if (pred != NO_OBJECT) pred.set_succ (succ);
if (succ != NO_OBJECT) succ.set_pred (pred);
self.destroy(); // destroy the node
TT (agg_H, T_LEAVE);
} // ** remove **
// **************************************************************************
sos_List_node sos_List_node::succ (sos_Int steps)
// **************************************************************************
{
T_PROC ("sos_List_node::succ");
TT (agg_H, T_ENTER; TI (steps));
sos_List_node node = self;
for (sos_Int i = 1;
(i <= steps) AND (node != NO_OBJECT);
i++)
node = node.get_succ ();
TT (agg_H, T_LEAVE; TI(i));
return node;
} // ** succ **
// **************************************************************************
sos_List_node sos_List_node::pred (sos_Int steps)
// **************************************************************************
{
T_PROC ("sos_List_node::pred");
TT (agg_H, T_ENTER; TI (steps));
sos_List_node node = self;
for (sos_Int i = 1;
(i <= steps) AND (node != NO_OBJECT);
i++)
node = node.get_pred();
TT (agg_H, T_LEAVE; TI(i));
return node;
} // ** pred **